import os
import sys
import time
import psutil
import win32com.client
import openpyxl
import logging

# 获取应用程序运行目录
# PyInstaller打包时会创建临时目录，通过sys._MEIPASS可以访问
def get_base_path():
    # 检查是否是PyInstaller打包后的环境
    if hasattr(sys, '_MEIPASS'):
        # 打包后的临时目录
        return sys._MEIPASS
    else:
        # 开发环境下的脚本目录
        return os.path.dirname(os.path.abspath(__file__))

# 配置日志
logging.basicConfig(filename='app.log', level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s')

def kill_all_excel():
    """强制杀死所有Excel进程"""
    for proc in psutil.process_iter(['name']):
        if proc.info['name'] in ['EXCEL.EXE', 'excel.exe']:
            try:
                proc.kill()
                print(f"已杀死残留的Excel进程（PID: {proc.pid}）")
            except Exception as e:
                print(f"杀死Excel进程失败：{e}")
    time.sleep(1)

def creat_ght():
    print("程序开始运行...")
    # 获取基础路径（兼容开发环境和打包环境）
    base_dir = get_base_path()
    # 获取桌面路径
    desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
    # 从桌面获取data.xlsx，如果没有则新建
    data_source_path = os.path.join(desktop_path, "data.xlsx")  # 目标信息数据源
    
    # 从data.xlsx第一个sheet第一行第四列获取Excel文件名
    import win32com.client as win32
    excel_app_source = None
    try:
        # 创建Excel应用实例
        excel_app_source = win32.Dispatch('Excel.Application')
        excel_app_source.Visible = False
        excel_app_source.DisplayAlerts = False
        
        # 打开data.xlsx文件
        source_workbook = excel_app_source.Workbooks.Open(data_source_path)
        # 访问第一个sheet
        source_sheet = source_workbook.Sheets(1)
        # 获取第一行第四列(D1)的单元格值作为文件名
        excel_filename = source_sheet.Cells(1, 4).Value+".xlsx"
        
        # 如果获取不到文件名，使用默认值
        if not excel_filename:
            return "错误：未在data.xlsx的D1单元格中指定Excel文件名"
        
            
        # 使用获取的文件名构建excel_path
        excel_path = os.path.join(base_dir, excel_filename)  # 处理和截图的Excel文件
        
        # 关闭工作簿
        source_workbook.Close(False)
    except Exception as e:
        print(f"获取Excel文件名时出错: {e}")
        # 使用默认文件名
        excel_path = os.path.join(base_dir, "C2.xlsx")
    finally:
        # 关闭Excel应用
        if excel_app_source:
            excel_app_source.Quit()
    # 将结果保存到桌面
    res_dir = os.path.join(desktop_path, "规划图")
    os.makedirs(res_dir, exist_ok=True)
    print(f"基础路径: {base_dir}")
    print(f"使用Excel文件路径: {excel_path}")
    print(f"结果保存路径: {res_dir}")

    if not os.path.exists(excel_path):
        print(f"错误：未找到 {excel_path}")
        return

    # 数据列配置
    col_time = 1    # A列
    col_student = 2 # B列
    col_teacher = 3 # C列
    row = 2         # 从第2行开始

    # 预处理
    kill_all_excel()
    
    # 使用win32com.client操作Excel
    excel_app = None
    workbook = None
    try:
        # 创建Excel应用实例 - 设为不可见，后台运行
        excel_app = win32com.client.Dispatch("Excel.Application")
        excel_app.Visible = False  # 设为不可见，后台运行
        excel_app.DisplayAlerts = False
        
        # 不再强制将Excel窗口置于前台
        
        print(f"Excel应用已启动，PID: {excel_app.Hwnd}")
        
        # 打开工作簿
        workbook = excel_app.Workbooks.Open(os.path.abspath(excel_path))
        
        # # 检查工作表数量
        # if workbook.Sheets.Count < 2:
        #     print("错误：至少需要2个工作表")
        #     return
        
        # 获取工作表
        sheet1 = workbook.Sheets(1)  # 第一个工作表
        original_sheet_name = workbook.Sheets(1).Name  # 保存第二个工作表名称
        sheet2 = workbook.Sheets(original_sheet_name)  # 使用名称引用
        print(f"第二个工作表名称：{original_sheet_name}")
        
        # 常量定义
        xlScreen = 1
        xlBitmap = 2
        
        while True:
            # 从data.xlsx的第一个sheet获取目标信息
            # 如果文件不存在，创建一个新的Excel文件
            if not os.path.exists(data_source_path):
                
                wb_new = openpyxl.Workbook()
                ws_new = wb_new.active
                # 添加表头
                ws_new.cell(row=1, column=col_time).value = "时间"
                ws_new.cell(row=1, column=col_student).value = "学员姓名"
                ws_new.cell(row=1, column=col_teacher).value = "老师姓名"
                wb_new.save(data_source_path)
                wb_new.close()
                return (f"未找到{data_source_path}，正在创建新文件...")
            
            wb_data_source = openpyxl.load_workbook(data_source_path, read_only=True)
            data_sheet = wb_data_source.worksheets[0]  # data.xlsx的第一个工作表
            time_val = data_sheet.cell(row=row, column=col_time).value
            student_val = data_sheet.cell(row=row, column=col_student).value
            teacher_val = data_sheet.cell(row=row, column=col_teacher).value
            wb_data_source.close()

            if not time_val and not student_val and not teacher_val:
                print("已读取完所有数据")
                break

            if not student_val:
                print(f"第{row}行学员姓名为空，跳过")
                row += 1
                continue

            print(f"\n处理第{row}行：学员={student_val}")

            # 写入数据
            try:
                sheet2.Range("I1").Value = time_val if time_val else ""
                sheet2.Range("J1").Value = student_val
                sheet2.Range("K1").Value = teacher_val if teacher_val else ""
                workbook.Save()
                print("数据已写入第二个工作表")
                time.sleep(1)  # 给Excel时间更新
            except Exception as e:
                print(f"写入失败：{e}")
                logging.error(f"写入失败：{e}")
                row += 1
                continue

            # 导出图片
            try:
                # 确保sheet2被选中
                sheet2.Activate()
                
                # # 创建以老师姓名命名的文件夹
                # if teacher_val:
                #     teacher_dir = os.path.join(res_dir, teacher_val)
                #     os.makedirs(teacher_dir, exist_ok=True)
                # else:
                #     teacher_dir = res_dir
                # print(f"老师目录: {teacher_dir}")
                
                # 导出图片
                safe_name = student_val.replace("/", "-").replace("\\", "-").replace(":", "-")
                output_path = os.path.join(res_dir, f"{safe_name}.png")
                
                # 选择要截图的区域
                range_to_capture = sheet2.Range("A1:H57")
                range_to_capture.Select()
                
                # 后台运行模式下，不需要激活窗口
                excel_app.ScreenUpdating = True
                time.sleep(1)  # 给系统时间处理内容
                
                # 复制区域为图片
                range_to_capture.CopyPicture(xlScreen, xlBitmap)
                time.sleep(1)  # 确保复制到剪贴板
                
                # 创建临时工作表用于放置图片
                temp_sheet = None
                temp_sheet_name = "__TempImageExport"
                
                # 检查并删除已存在的临时工作表
                for s in workbook.Sheets:
                    if s.Name == temp_sheet_name:
                        s.Delete()
                        break
                
                # 添加新的临时工作表
                temp_sheet = workbook.Sheets.Add(Before=workbook.Sheets(1))
                temp_sheet.Name = temp_sheet_name
                temp_sheet.Activate()
                
                # 创建图表并设置大小
                chart_shape = temp_sheet.Shapes.AddChart()
                # 设置图表大小为1567x2403像素比例（Excel中的单位是磅，1像素≈0.75磅）
                chart_shape.Width = 1567 * 0.75  # 宽度缩小100像素，转换为Excel的磅单位
                chart_shape.Height = 2403 * 0.75
                
                # 粘贴图片到图表
                chart = chart_shape.Chart
                chart.Paste()
                time.sleep(1)  # 确保粘贴完成
                
                # 导出图片
                chart.Export(Filename=os.path.abspath(output_path))
                print(f"截图成功：{output_path}")
                
                # 清理 - 删除临时工作表
                sheet2.Activate()  # 先激活其他工作表
                temp_sheet.Delete()
                
            except Exception as e:
                print(f"截图失败：{e}")
                logging.error(f"截图失败：{e}")

            row += 1

    except Exception as e:
        print(f"主程序错误：{e}")
        logging.error(f"主程序错误：{e}")
    finally:
        # 清理资源
        try:
            if workbook:
                workbook.Close(SaveChanges=False)
        except:
            pass
        try:
            if excel_app:
                excel_app.Quit()
        except:
            pass
        # 确保所有Excel进程都被杀死
        kill_all_excel()
        print("\n所有操作完成")
        return "脚本执行完毕，快说，谢谢蒋来~"

if __name__ == "__main__":
    print("form to JiangLai")
    main()

